<?php

/**
 * Warlock :: User
 *
 * Warlock is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 *
 * @package    warlock
 * @author     David Cole <neophyte@sourcetutor.com>
 * @license    GNU/GPL v2
 */

class User extends Object
{
    var $_Access;

    /**#@+
     * Required Core Objects
     *
     * These are references to the core objects required by this
     * class.
     *
     * @access private
     * @var    object
     */
    var $_Observer;
    var $_Error;
    var $_Session;
    var $_DAL;
    var $_Profiler;
    /**#@-*/

    /**
     * User Data Object
     *
     * @var DAL_DataObjectRow
     * @access public
     */
    var $DataObject;

    /**
     * Logged In
     *
     * @var bool
     * @access private
     */
    var $_IsLoggedIn;

    function __construct()
    {
        // Add self to vault
        Vault::Add('User', &$this);

        // Grab references to required objects
        $this->_Error    = &Vault::Get('Debug_Error');
        $this->_Observer = &Vault::Get('Observer');
        $this->_Session  = &Vault::Get('Session');
        $this->_DAL      = &Vault::Get('DAL');
        $this->_Profiler = &Vault::Get('Debug_Profiling');

        /*
         * Based on existing session data determine
         * whether or not a user is already logged in.
         */

        $this->_Profiler->Start('Initialise User');

        $user_id = &$this->_Session->Get('user');

        if ((is_numeric($user_id)) && ($user_id > 1))
        {
            $this->_IsLoggedIn = true;
            $this->DataObject = $this->_DAL->Select('user', $user_id);            
        }

        if (!is_object($this->DataObject))
        {
            $this->_IsLoggedIn = false;
            $this->DataObject = $this->_DAL->Select('user', 1);
        }

        $this->_Error->Log('User :: Logged In As \''.$this->DataObject->username.'\'', W_LOG_DEBUG);
        
        $this->_Access = false;
        $this->_Profiler->Stop();
    }

    function Login($username, $password)
    {
        $this->_Error->Log('User :: Attempting Login of \''.$username.'\'', W_LOG_DEBUG);
        $this->_Access = false;

        /*
         * Attempt to authenticate user based on the supplied
         * user credentials
         */

        $results = $this->_Observer->RaiseEvent('onAuthenticate', array($username, $password));

        for ($i = 0; $i < count($results); $i++)
        {
            switch (true)
            {                
                case ($results[$i] === false):
                    $this->_Error->Log('User :: Plugin Authentication Failed', W_LOG_DEBUG);
                    break;
                    return false;
                case ($results[$i] === true);
                    continue;
                case is_object($results[$i]):                    
                    $this->_IsLoggedIn = true;
                    $this->DataObject  = $results[$i];
                    break;
            }
        }        
        
        /*
         * User is authenticated, give other plugins the opportunity to
         * log the user in.
         */

        if (!$this->_IsLoggedIn)
        {
            $this->_Error->Log('User :: Authentication Failed', W_LOG_DEBUG);
            return false;
        }
        else
            if (in_array(false, $this->_Observer->RaiseEvent('onLogin', array($username, $password))))
                return false;

        // User is fully logged in, hazzah !
        $this->_Error->Log('User :: Login Successful', W_LOG_DEBUG);
        return true;
    }

    function Logout()
    {
        $this->_Access = false;

        /*
         * Give all plugins the opportunity to log the user out
         * primarily clearing their respective session data etc ..
         */

        if ($this->_IsLoggedIn)
        {
            if (in_array(false, $this->_Observer->RaiseEvent('onLogout', array($this->DataObject->id, $this->DataObject->email))))
                return false;
        }
        else
            return false;

        /*
         * User logged out update self with details of an
         * anonymous user
         */

        $this->_IsLoggedIn = false;
        $this->DataObject  = $this->_DAL->Select('user', 1);

        return true;
    }

    function HasAccess()
    {
        if ($this->DataObject->gid == 2)
            return true; // Users in Group 2 can do anything
        else
        {
            $args       = func_get_args();
            $permission = implode('_', $args);

            if ($this->_Access === false)
                $this->_LoadAccess();

            return array_key_exists($permission, $this->_Access);
        }
    }

    function IsLoggedIn()
    {
        return $this->_IsLoggedIn;
    }

    function _LoadAccess()
    {
        $this->_Access = array();
        $rs            = $this->_DAL->Select('access', array('gid' => $this->DataObject->gid), null, null, null, 'ASSOC');

        while ($r = $rs->FetchRow())
            $this->_Access[$r['label']] = true;
    }

}

?>